package com.cloudwise.aop;

import cn.hutool.core.util.ReflectUtil;
import com.cloudwise.entity.Log;
import com.cloudwise.entity.User;
import com.cloudwise.service.LogService;
import com.cloudwise.util.MyUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * @author ：王
 * @description：日志切面类
 * @modified By：
 * @version: 1.0
 */
@EnableAspectJAutoProxy
@Component
@Aspect
public class LogAspect {
    @Autowired
    private LogService logService;

    /**
     * 切入点表达式,切入到所有controller中的所有方法
     */
    @Pointcut("execution (  *  com.cloudwise.controller.*.*(..))")
    public  void p(){}
    @Pointcut("execution (  *  com.cloudwise.controller.*.insert(..))")
    public  void pService(){}

    @Pointcut("@annotation(com.cloudwise.aop.LogAnn)")
    public  void q(){}

    @Around("p()")
    public  Object myEnhance(ProceedingJoinPoint joinPoint ){
        //获取方法的参数
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        //保存日志信息到数据库中
        Log  log= new Log();
        Subject subject = SecurityUtils.getSubject();
        Object principal = subject.getPrincipal();
        User user=new User();
        if(principal!=null){
             user= (User) principal;
        }
        log.setLoginName(user.getLoginName());
        log.setUserName(user.getUserName());
        //获取请求的ip地址
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String remoteAddr = request.getRemoteAddr();
        log.setIp(remoteAddr);
        //获取类名
        String className = joinPoint.getTarget().getClass().getName();
        log.setClassName(className);
        //获取方法名
        String[] split = signature.toString().split("\\.");
        String method = split[split.length - 1];
        log.setMethodName(method);
        //获取参数
        String paramString = Arrays.toString(args);
        log.setParams(paramString);
        //设置时间
        log.setCreateTime(new Date());
        logService.save(log);
        try {
            //业务方法执行
            Object proceed = joinPoint.proceed(args);
            return proceed;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    @Before("pService()")
    public  void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("方法名："+name);
        Object[] args = joinPoint.getArgs();
        if(args.length==1){
            //保存方法
            ReflectUtil.invoke(args[0],"setCreateTime",new Date());
            ReflectUtil.invoke(args[0],"setCreateBy", MyUtil.getCurrentUser().getLoginName());
        }

    }
}
